import decimal
from django.db.models import Q

from rest_framework import viewsets
from rest_framework.pagination import PageNumberPagination
from rest_framework.decorators import action

from utils.decorators.responses import json_response, FlagException
from .models import UserProfile
from .serializers import GetUserSuperSerializer, PostUserSuperSerializer, GetUserAllowSerializer, \
    GetUserInfoSerializer, ChangePassSerializer, ScanUserSerializer, ScanUserRetSerializer

from .filterBackends import UserAllowPermissionFilterBackend
from rest_framework_swagger.renderers import OpenAPIRenderer, SwaggerUIRenderer
from rest_framework.decorators import api_view, renderer_classes
from rest_framework import response, schemas
from rest_framework import permissions


from utils.decorators.auth import is_superuser, is_authenticated
from .mycaches import user_cache


@api_view()
@renderer_classes([SwaggerUIRenderer, OpenAPIRenderer])
def schema_view(request):
    generator = schemas.SchemaGenerator(title='系统API')
    return response.Response(generator.get_schema(request=request))


class UsersPagination(PageNumberPagination):
    page_size = 20
    page_query_param = "page"
    page_size_query_param = 'limit'

    # 最大能请求几条
    max_page_size = 100


class UserProfileViewSet(viewsets.mixins.CreateModelMixin,
                         viewsets.mixins.UpdateModelMixin,
                         viewsets.mixins.ListModelMixin,
                         viewsets.GenericViewSet):
    permission_classes = [permissions.IsAuthenticated]
    pagination_class = UsersPagination
    queryset = UserProfile.objects.all()
    serializer_class = PostUserSuperSerializer
    filter_backends = [UserAllowPermissionFilterBackend]

    @json_response
    def list(self, request, *args, **kwargs):
        query = UserProfile.objects.all().filter(isDelete=False)

        serializer = None
        if self.request.user.is_superuser:
            filterUPN = request.query_params.get('filterUPN', None)
            if filterUPN:
                query = query.filter(Q(username__contains=filterUPN) | Q(name__contains=filterUPN)
                                     | Q(phoneNumber__contains=filterUPN))
            queryset = self.paginate_queryset(query)
            serializer = GetUserSuperSerializer(queryset, many=True)
            return self.get_paginated_response(serializer.data).data
        else:
            user = request.user
            serializer = GetUserAllowSerializer(user)
            return serializer.data

    @is_superuser
    @json_response
    @action(methods=['post'], detail=False, serializer_class=ScanUserSerializer)
    def scan(self, request):
        query = UserProfile.objects.all().filter(isDelete=False)
        serializer = ScanUserSerializer(data=request.data)
        try:
            serializer.is_valid(raise_exception=True)
            filter_upn = serializer.data['filter_upn']
            if filter_upn:
                query = query.filter(Q(username__contains=filter_upn) | Q(name__contains=filter_upn)
                                     | Q(phoneNumber__contains=filter_upn))
            queryset = self.paginate_queryset(query)
            serializer = ScanUserRetSerializer(queryset, many=True)
            return self.get_paginated_response(serializer.data).data
        except Exception as e:
            raise FlagException(False, 400, e.__str__())

    @is_superuser
    @json_response
    def create(self, request, *args, **kwargs):
        serializer = PostUserSuperSerializer(data=request.data)
        try:
            serializer.is_valid(raise_exception=True)
            serializer.save()
            # return Response({
            #     "flag": True,
            #     "code": 0,
            #     "errorMsg": "操作成功"
            # }, status=200)
            return
        except Exception as e:
            # return Response({
            #     "flag": False,
            #     "code": 400,
            #     "errorMsg": e.__str__()
            # }, status=208)
            raise FlagException(False, 400, e.__str__())

    @json_response
    def update(self, request, *args, **kwargs):
        user = UserProfile.objects.get(id=request.data['id'])
        serializer = PostUserSuperSerializer(user, data=request.data)
        try:
            serializer.is_valid(raise_exception=True)
            serializer.save()
            # return Response({
            #     "flag": True,
            #     "code": 0,
            #     "errorMsg": "操作成功"
            # }, status=200)
            return
        except Exception as e:
            # return Response({
            #     "flag": False,
            #     "code": 400,
            #     "errorMsg": e.__str__()
            # }, status=208)
            raise FlagException(False, 400, e.__str__())

    # @is_authenticated
    @json_response
    @action(methods=['post'], detail=False, serializer_class=ChangePassSerializer)
    def change_pass(self, request):
        # self.serializer_class = ChangePassSerializer
        # user = get_object_or_404(self.queryset)
        user = request.user
        serializer = ChangePassSerializer(data=request.data)
        try:
            if serializer.is_valid(raise_exception=True):
                if not user.check_password(serializer.data['old_pass']):
                    raise FlagException(False, 400, '修改失败')
                user.set_password(serializer.data['new_pass'])
                user.save()
                # return JsonResponse({'flag': True, 'code': 0, 'errorMsg': '操作成功'}, status=200)
                return
        except Exception as e:
            raise FlagException(False, 400, e.__repr__())

    # @is_authenticated
    @json_response
    @action(methods=['get'], detail=False)
    def user_info(self, request):
        data = request.user
        serializer = GetUserInfoSerializer(data)
        return serializer.data

    @is_superuser
    @json_response
    @action(methods=['get'], detail=False)
    def user_count(self, request):

        return {'count': user_cache.get_user_count()}

    @is_superuser
    @json_response
    @action(methods=['get'], detail=False)
    def user_pre_deposit_count(self, request):

        # count = UserProfile.objects.aggregate(Sum('preDeposit'))
        # .annotate(preDepositCount=Sum('preDeposit'))
        return {'count': user_cache.get_pre_deposit_count()}
